/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Seniat;

import BD.Retenciones;
import gui.Ventana;
import gui.VentanaArchivo;
import gui.VentanaBusqueda;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.swing.JOptionPane;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

/**
 *
 * @author ARMGARCES
 */
public class Seniat {
    public  static final String PERSISTENCE_UNIT_NAME = java.util.ResourceBundle.getBundle("Seniat/properties").getString("persistence");
    private static Ventana ventana;
    private static VentanaArchivo ventanaArchivo;
    private static VentanaBusqueda ventanaBusqueda;
    private static int ano  = 0;
    private static int cont = 0;
    private static int act  = 0;
    private static List archivo = new ArrayList();
    private static EntityManagerFactory factory;
    private static EntityManager em;
    private Seniat() {
        
    }
    
    public static Seniat getInstance() {
        return SeniatHolder.INSTANCE;
    }

    private static class SeniatHolder {

        private static final Seniat INSTANCE = new Seniat();
    }
    
    public void openVentana() {
        ventana = new Ventana();
        ventana.centrarVentana();
        ventana.setVisible(true);
    }
    
    /**
     * 
     * @param vent 
     */
    public void openVentanaArchivo(Ventana vent) {
        ventanaArchivo = new VentanaArchivo(vent);
        ventanaArchivo.centrarVentana();
        ventanaArchivo.setVisible(true);
    }
    /**
     * 
     * @param vent 
     */
    public void openVentanaBusqueda(Ventana vent) {
        ventanaBusqueda = new VentanaBusqueda(vent);
        ventanaBusqueda.centrarVentana();
        ventanaBusqueda.setVisible(true);
    }
    /**
     * 
     * @param archivo
     * @return 
     */
    private void iniciarCont(List archivo){
        for (int j = 0; j < archivo.size(); j++) {
            List list = (List) archivo.get(j);
            cont += list.size()-27;
        }
    }
    
    /**
     * 
     * @param archivo 
     */
    private void sendData(List archivo,String path){
        
        for (int k = 0; k < archivo.size(); k++) {
            List list = (List) archivo.get(k);
            insertData(list,path);
            
        }
    }
    /**
     * 
     * @param sheetData 
     */
    private void insertData(List sheetData,final String path) {
        //
        // Iterates the data and print it out to the console.
        //
        ventanaArchivo.iniciarProgressBar(0,cont);
        
        int section = 500;
        int size = sheetData.size()-2;
        int loops = (int) Math.ceil(size/section);
                
        for (int i = 0; i < loops; i++) {
            int begin = 0;
            int end = 0;
            if(i == 0){
                begin = 25;
                end = section;
            }else{
                begin = i*section;
                if(i == loops-1){
                    end = (i*section)+(size-(i*section));
                }else{
                    end = (i*section)+section;
                    
                }                
            }
            
            final List list = (List) sheetData.subList(begin, end);
            
            Thread t = new Thread(new Runnable() {                
                @Override
                public void run() {
                    try{
                    for (int i = 0; i < list.size(); i++) {
                        act++;
                        List _list = (List) list.get(i);
                        Retenciones retencion = new Retenciones(_list);
                        retencion.insert(ventanaArchivo,path);
                        ventanaArchivo.updateProgressBar(act);
                    }
                    }catch(Exception e){
                        e.printStackTrace();
                        String mnsj  = "Error Inesperado, por Favor Intente Luego! "+e.getMessage();
                        String title = "Error de Sistema";
                        JOptionPane.showMessageDialog(ventana,mnsj,title, JOptionPane.ERROR_MESSAGE);
                    }
                }
            });
            
            t.start();
        }
    }
    
    /**
     * 
     * @param k 
     */
    private List readFile(String file){        
        
        // Create an ArrayList to store the data read from excel sheet.      
        List fila = new ArrayList();
        FileInputStream fis = null;
        try {
            // Create a FileInputStream that will be use to read the 
            // excel file.
            fis = new FileInputStream(file);
            // Create an excel workbook from the file system.
            HSSFWorkbook workbook = new HSSFWorkbook(fis);
            // Get the first sheet on the workbook.
            HSSFSheet sheet = workbook.getSheetAt(0);
            //
            // When we have a sheet object in hand we can iterator on 
            // each sheet's rows and on each row's cells. We store the 
            // data read on an ArrayList so that we can printed the 
            // content of the excel to the console.
            //
            Iterator rows = sheet.rowIterator();
            int i=0;
            while (rows.hasNext()) {
                HSSFRow row = (HSSFRow) rows.next();
                Iterator cells = row.cellIterator();
                List data = new ArrayList();
                while (cells.hasNext()){
                    HSSFCell cell = (HSSFCell) cells.next();
                    data.add(cell);
                }
                fila.add(data);
            }
            if (fis != null) {
                fis.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            return fila;
        }
    }
    
    /**
     * 
     * @param file 
     */
    public void procesarArchivo(File file) {
      if(file != null){
        cont = 0;
        act  = 0;
        //
        try{
            archivo.add(readFile(file.getAbsolutePath()));
            iniciarCont(archivo);
            sendData(archivo,file.getName());            
        }catch(Exception e){
            e.printStackTrace();            
        }
      }else{
        //
      }
    }
    
    /**
     * 
     * @param _tipo 
     * @param _param
     * @param _mes
     * @param _ano
     * @return 
     */
    public List<Retenciones> buscar(int _tipo,String _param,int _mes,int _ano){
        try{            
            factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
            em = factory.createEntityManager();
            
            List<Retenciones> result = new ArrayList<Retenciones>();
            //use entity manager to retrieve named query
            String query = Utils.getQuery(_tipo);
            Query find = em.createQuery(query);
            switch(_tipo){
                case 0:
                    find.setParameter("rifAgente",_param);
                    find.setParameter("mes",Utils.formatearMes(_mes,_ano));
                    break;
                case 1:
                    find.setParameter("nrodocumento",_param+".0");
                    break;
                case 2:
                    find.setParameter("nrocontrol","00-"+_param);
                    break;
                case 3:
                    find.setParameter("nroafectado",_param+".0");
                    break;
                case 4:
                    find.setParameter("monto",Double.parseDouble(_param));
                    break;
            }
            
            //execute query and get results
            result = find.getResultList();     
            System.out.println("result = " + result.size());
            em.clear();
            em.close();
            factory.close();
            return result;
        }catch(Exception e){
            e.printStackTrace();            
        }
        return null;
    }
}
